package com.itmck.controller;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.TimeInterval;
import com.alibaba.fastjson.JSON;
import com.itmck.common.bo.ApiResponse;
import com.itmck.common.easyexcel.BatchReadListener;
import com.itmck.dao.UserBatchInsertMapper;
import com.itmck.pojo.DataExcelImportRespVO;
import com.itmck.pojo.User;
import com.itmck.pojo.UserExcel;
import com.itmck.service.ExcelService;
import com.itmck.service.FunctionDatasourceService;
import com.itmck.common.easyexcel.EasyExcelUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


@Slf4j
@RestController
@Api(value = "ExcelController", tags = "使用easyExcel操作excel")
public class ExcelController {

    @Resource
    private ExcelService excelService;

    @Resource
    private UserBatchInsertMapper userBatchInsertMapper;

    @Resource
    private FunctionDatasourceService functionDatasourceService;


    @PostMapping("/export")
    @ApiOperation(value = "浏览器直接导出excel", notes = "excel导出案例")
    public void export(HttpServletResponse response) throws IOException {
        try {
            //开始计时
            TimeInterval timer = DateUtil.timer();
            EasyExcelUtil.writeWeb(response, UserExcel.class, list(), "qwe", "1");
            //结束计时
            long interval = timer.interval();
            log.info("导入数据共花费：{}s", interval / 1000);
        } catch (Exception e) {
            response.reset();
            response.setStatus(500);
            response.setContentType("application/json");
            response.setCharacterEncoding("utf-8");
            Map<String, String> map = new HashMap<>();
            map.put("status", "failure");
            map.put("message", "下载文件失败" + e.getMessage());
            response.getWriter().println(JSON.toJSONString(map));
        }
    }


    public List<UserExcel> list() {
        List<UserExcel> list = new ArrayList<>();
        for (int i = 0; i < 10000; i++) {
            list.add(new UserExcel("mck" + i, "qwe" + i));
        }
        return list;
    }


    @ApiOperation(value = "同步读取模型，小批量数据读取", notes = "excel导入案例", consumes = "multipart/form-data")
    @PostMapping("readSmallSync")
    public ApiResponse<String> readSmallAsync(@RequestParam("file") MultipartFile file) {
        try (InputStream inputStream = file.getInputStream()) {
            List<UserExcel> ts = EasyExcelUtil.syncReadModel(inputStream, UserExcel.class);

            //进行业务逻辑的处理
            // XXX
            //进行业务逻辑的处理
        } catch (Exception e) {
            log.error("异步读取excel进行入库操作失败");
        }
        return ApiResponse.ok("my name is:" + file.getName());
    }


    @ApiOperation(value = "使用监听器异步导入方式1", notes = "excel导入案例", consumes = "multipart/form-data")
    @PostMapping("read2")
    public ApiResponse<String> read1(@RequestParam("file") MultipartFile file) {
        //开始计时
        TimeInterval timer = DateUtil.timer();
        //此方式较为灵活，可以自己控制要插入的数据
        try (InputStream inputStream = file.getInputStream()) {
            EasyExcelUtil.asyncReadListener(
                    inputStream,
                    new BatchReadListener<>(
                            dataList -> {
                                //  excelService.saveData(dataList);
                                List<User> users = new ArrayList<>();
                                dataList.forEach(userExcel -> {
                                    User user = new User();
                                    user.setUserName(userExcel.getUserName());
                                    user.setPassword(userExcel.getPassword());
                                    users.add(user);
                                });
                                userBatchInsertMapper.insertBatchSomeColumn(users);
                            }
                    ),
                    UserExcel.class);
        } catch (Exception e) {
            log.error("异步读取excel进行入库操作失败");
        }
        //结束计时
        long interval = timer.interval();
        log.info("导入数据共花费：{}s", interval / 1000);


        return ApiResponse.ok("my name is:" + file.getName());
    }

    @ApiOperation(value = "使用监听器异步导入方式2", notes = "excel导入案例", consumes = "multipart/form-data")
    @PostMapping("read")
    public ApiResponse<String> read(@RequestParam("file") MultipartFile file) {
        //开始计时
        TimeInterval timer = DateUtil.timer();
        try (InputStream inputStream = file.getInputStream()) {
            //此种方式是针对于不需要校验数据库是否存在重复记录的情况
            EasyExcelUtil.asyncReadListener(
                    inputStream,
                    new BatchReadListener<>(userBatchInsertMapper, User.class),
                    UserExcel.class);
        } catch (Exception e) {
            log.error("异步读取excel进行入库操作失败");
        }
        //结束计时
        long interval = timer.interval();
        log.info("导入数据共花费：{}s", interval / 1000);
        return ApiResponse.ok("my name is:" + file.getName());
    }


    @PostMapping("/create-sw-mbqcdss")
    @ApiOperation("异步读取excel进行入库操作")
    public ApiResponse<DataExcelImportRespVO> createFunctionDatasourceAndSwMbqcdss(@RequestParam("file") MultipartFile file
    ) throws Exception {
        long filesize = file.getSize();
        log.info("导入文件大小：{}k", filesize / 1024);
        return ApiResponse.ok(functionDatasourceService.createFunctionDatasourceAndSwMbqcdss(file));
    }
}

